package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.entity.views.StudentCourse;
import com.xmy.cultivate.exception.CommonException;
import com.xmy.cultivate.mapper.CourseMapper;
import com.xmy.cultivate.mapper.OrderDetailMapper;
import com.xmy.cultivate.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.util.CommonUtil;
import com.xmy.cultivate.util.IdWorker;
import com.xmy.cultivate.util.ResultCode;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 课程表 服务实现类
 * </p>
 *
 * @author min
 * @since 2022-07-26
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    @Lazy
    private ICoursePriceSchoolService iCoursePriceSchoolService;

    @Autowired
    @Lazy
    private ICoursePricingService iCoursePricingService;

    @Autowired
    @Lazy
    private IAppointSchoolService iAppointSchoolService;

    @Autowired
    @Lazy
    private CourseMapper courseMapper;

    @Autowired
    @Lazy
    private IGradeService iGradeService;

    @Autowired
            @Lazy
    IdWorker idWorker;

    @Autowired
    @Lazy
    IRenewDataService iRenewDataService;

    @Autowired
    @Lazy
    ISubjectsService iSubjectsService;

    @Autowired
    @Lazy
    IQuarterService iQuarterService;

    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Autowired
    @Lazy
    IStudentGradeService iStudentGradeService;


    private Integer appointSchoolType = 1;//1课程指定校区,2机构帐号指定校区，3员工所属部门，4上课校区范围（添加员工）,5、角色的适用校区

    @Autowired
    @Lazy
    ICourseSchedulingDetailService iCourseSchedulingDetailService;

    @Autowired
    IStudentNewsService iStudentNewsService;


    public boolean saveTo(Course course){

        List<CoursePriceSchool> priceSchoolList = new ArrayList<>();
        List<CoursePricing> coursePricingList = new ArrayList<>();
        List<AppointSchool> appointSchoolList = new ArrayList<>();

        course.setId(idWorker.nextId());//自定义id

        Iterator<CoursePriceSchool> it = course.getPriceSchoolList().iterator();
        while (it.hasNext()){
            CoursePriceSchool coursePriceSchool = it.next();
            coursePriceSchool.setId(idWorker.nextId());
            coursePriceSchool.setCourseId(course.getId());//设置所属课程id

            //coursePriceSchool.setCourseId();
            priceSchoolList.add(coursePriceSchool);

            Iterator<CoursePricing> coursePricingIterator = coursePriceSchool.getCoursePricingList().iterator();
            while (coursePricingIterator.hasNext()){
                CoursePricing coursePricing = coursePricingIterator.next();
                coursePricing.setPriceSchoolId(coursePriceSchool.getId());//设置id
                coursePricing.setCourseId(course.getId());//设置课程id
                coursePricing.setSchoolId(coursePriceSchool.getSchoolId());//所属学校id
                coursePricing.setChargeMode(course.getChargeMode());
                if(coursePricing.getCount()!=0){
                    BigDecimal price = coursePricing.getPrice();
                    //BigDecimal count = new BigDecimal(String.valueOf(coursePricing.getCount()));
                    //BigDecimal count = new BigDecimal(String.valueOf(coursePricing.getCount()));

                    //每三个课时金额
                    BigDecimal unitCount = new BigDecimal(coursePricing.getCount()).divide(new BigDecimal(3),BigDecimal.ROUND_UP);

                    //BigDecimal unitPrice = price.divide(unitCount,0,BigDecimal.ROUND_HALF_UP);
                    BigDecimal unitPrice = coursePricing.getPrice().add(coursePricing.getServePrice()).divide(unitCount,BigDecimal.ROUND_HALF_UP);
                    coursePricing.setUnitPrice(unitPrice);

                    BigDecimal allPrice = new BigDecimal(0);
                    allPrice = allPrice.add(coursePricing.getPrice());
                    allPrice = allPrice.add(coursePricing.getServePrice());
                    allPrice = allPrice.add(coursePricing.getMaterialsPrice());
                    coursePricing.setAllPrice(allPrice);

                }
                coursePricingList.add(coursePricing);
            }
        }

        Iterator<AppointSchool> appointSchoolIterator = course.getAppointSchoolList().iterator();
        while (appointSchoolIterator.hasNext()){
            AppointSchool appointSchool = appointSchoolIterator.next();
            appointSchool.setForId(course.getId());//设置所属资源id
            appointSchool.setType(appointSchoolType);
            appointSchoolList.add(appointSchool);
        }

        this.save(course);
        iCoursePriceSchoolService.saveBatch(priceSchoolList);
        iCoursePricingService.saveBatch(coursePricingList);
        iAppointSchoolService.saveBatch(appointSchoolList);
        return  true;
    }

    @Transactional
    public boolean updateTo(Course course,List schoolIdList){

        //System.out.println(course);
        List<CoursePriceSchool> priceSchoolList = new ArrayList<>();
        List<CoursePricing> coursePricingList = new ArrayList<>();
        List<AppointSchool> appointSchoolList = new ArrayList<>();

        List<CoursePriceSchool> upPriceSchoolList = new ArrayList<>();
        List<CoursePricing> upCoursePricingList = new ArrayList<>();
        List<AppointSchool> upAppointSchoolList = new ArrayList<>();

        Set<Long> atPriceSchool = new HashSet<>();
        Set<Long> atCoursePricing = new HashSet<>();
        Set<Long> atAppointSchool = new HashSet<>();

        Course courseOld = courseMapper.findOne(course.getId());

        QueryWrapper<AppointSchool> appointSchoolQueryWrapper = new QueryWrapper<>();
        appointSchoolQueryWrapper.eq("for_id",course.getId());
        appointSchoolQueryWrapper.eq("type",appointSchoolType);
        iAppointSchoolService.remove(appointSchoolQueryWrapper);


        //判断选择的开课校区类型与原来的是否一样
        if(courseOld.getOpeningSchoolType()!= course.getOpeningSchoolType()){

            //课程价格指定学校
            QueryWrapper<CoursePriceSchool> coursePriceSchoolQueryWrapper = new QueryWrapper<>();
            coursePriceSchoolQueryWrapper.eq("course_id",course.getId());
            iCoursePriceSchoolService.remove(coursePriceSchoolQueryWrapper);

            //指定学校价格详细
            QueryWrapper<CoursePricing> coursePricingQueryWrapper = new QueryWrapper<>();
            coursePricingQueryWrapper.eq("course_id",course.getId());
            iCoursePricingService.remove(coursePricingQueryWrapper);

            //指定校区
            QueryWrapper<AppointSchool> appointSchoolQueryWrapperUp =  new QueryWrapper<>();
            appointSchoolQueryWrapperUp.eq("for_id",course.getId());
            appointSchoolQueryWrapperUp.eq("type",appointSchoolType);
            iAppointSchoolService.remove(appointSchoolQueryWrapperUp);

        }else {
            //course.setId(idWorker.nextId());//自定义id
            /*for(CoursePriceSchool coursePriceSchool:course.getPriceSchoolList()){
                for (CoursePricing coursePricing:coursePriceSchool.getCoursePricingList()){

                }
            }*/

        }

        Iterator<CoursePriceSchool> it = course.getPriceSchoolList().iterator();
        while (it.hasNext()){
            CoursePriceSchool coursePriceSchool = it.next();
            CoursePriceSchool coursePriceSchoolIsAt = iCoursePriceSchoolService.getCoursePriceSchoolByCourseId(course.getId(),coursePriceSchool.getSchoolId());
            if(coursePriceSchoolIsAt == null){
                //为添加
                coursePriceSchool.setId(idWorker.nextId());
                coursePriceSchool.setCourseId(course.getId());//设置所属课程id
                //coursePriceSchool.setCourseId();
                priceSchoolList.add(coursePriceSchool);
            }else{
                //修改
                coursePriceSchool.setId(coursePriceSchoolIsAt.getId());
                upPriceSchoolList.add(coursePriceSchool);
                atPriceSchool.add(coursePriceSchool.getId());//添加到已存在
            }

            Iterator<CoursePricing> coursePricingIterator = coursePriceSchool.getCoursePricingList().iterator();
            while (coursePricingIterator.hasNext()){
                CoursePricing coursePricing = coursePricingIterator.next();


                if(coursePricing.getCount() != 0){
                    BigDecimal price = new BigDecimal(String.valueOf(coursePricing.getPrice()));
                    //BigDecimal count = new BigDecimal(String.valueOf(coursePricing.getCount()));
                    //每三个课时金额
                    BigDecimal unitCount = new BigDecimal(coursePricing.getCount()).divide(new BigDecimal(3),BigDecimal.ROUND_UP);


                    //BigDecimal unitPrice = price.divide(unitCount,0,BigDecimal.ROUND_HALF_UP);
                    BigDecimal unitPrice = coursePricing.getPrice().add(coursePricing.getServePrice()).divide(unitCount,BigDecimal.ROUND_HALF_UP);
                    coursePricing.setUnitPrice(unitPrice);

                    BigDecimal allPrice = new BigDecimal(0);
                    allPrice = allPrice.add(coursePricing.getPrice());
                    allPrice = allPrice.add(coursePricing.getServePrice());
                    allPrice = allPrice.add(coursePricing.getMaterialsPrice());
                    coursePricing.setAllPrice(allPrice);
                }
                CoursePricing coursePricingIsAt = iCoursePricingService.getCoursePricingByCourseId(course.getId(),coursePriceSchool.getSchoolId(),coursePricing.getCount());
                if(coursePricingIsAt == null){
                    //添加
                    coursePricing.setId(idWorker.nextId());
                    coursePricing.setPriceSchoolId(coursePriceSchool.getId());//设置id
                    coursePricing.setCourseId(course.getId());//设置课程id
                    coursePricing.setSchoolId(coursePriceSchool.getSchoolId());//所属学校id
                    coursePricing.setChargeMode(course.getChargeMode());
                    coursePricingList.add(coursePricing);
                }else{
                    //修改
                    coursePricing.setId(coursePricingIsAt.getId());
                    upCoursePricingList.add(coursePricing);
                    atCoursePricing.add(coursePricing.getId());
                }

            }
        }

            /*QueryWrapper<AppointSchool> appointSchoolQueryWrapper = new QueryWrapper<>();
            System.out.print("course.getId:"+course.getId());
            appointSchoolQueryWrapper.eq("for_id",course.getId()).eq("type",appointSchoolType);

            iAppointSchoolService.remove(appointSchoolQueryWrapper);*/



        Iterator<AppointSchool> appointSchoolIterator = course.getAppointSchoolList().iterator();
        while (appointSchoolIterator.hasNext()){
            AppointSchool appointSchool = appointSchoolIterator.next();
            appointSchool.setId(idWorker.nextId());
            appointSchool.setForId(course.getId());//设置所属资源id
            appointSchool.setType(appointSchoolType);
            appointSchoolList.add(appointSchool);
        }

        //this.updateById(course);

        //删除
        if(atPriceSchool.size()>0){
            QueryWrapper<CoursePriceSchool> queryWrapper =  new QueryWrapper<>();
            queryWrapper.notIn("id",atPriceSchool);
            queryWrapper.eq("course_id",course.getId());
            //指定校区模式
            if(course.getOpeningSchoolType().getKey().equals(2)){
                //queryWrapper.in("school_id",schoolIdList);
            }

            iCoursePriceSchoolService.remove(queryWrapper);
        }

        if(atCoursePricing.size()>0){
            QueryWrapper<CoursePricing> queryWrapper =  new QueryWrapper<>();
            queryWrapper.notIn("id",atCoursePricing);
            queryWrapper.eq("course_id",course.getId());
            //queryWrapper.eq("price_school_id",course.getId());
            //指定校区模式
            if(course.getOpeningSchoolType().getKey().equals(2)){
                queryWrapper.in("school_id",schoolIdList);
            }
            iCoursePricingService.remove(queryWrapper);
        }

        if(atAppointSchool.size()>0){
            QueryWrapper<AppointSchool> queryWrapper =  new QueryWrapper<>();
            queryWrapper.notIn("id",atAppointSchool);
            queryWrapper.eq("for_id",course.getId());
            queryWrapper.eq("type",appointSchoolType);
            //指定校区模式
            if(course.getOpeningSchoolType().getKey().equals(2)){
                queryWrapper.in("school_id",schoolIdList);
            }
            iAppointSchoolService.remove(queryWrapper);
        }


        //新数据，批量添加
        if(priceSchoolList.size()>0)
            iCoursePriceSchoolService.saveBatch(priceSchoolList);
        if(coursePricingList.size()>0)
            iCoursePricingService.saveBatch(coursePricingList);
        if(appointSchoolList.size()>0)
            iAppointSchoolService.saveBatch(appointSchoolList);

        //批量修改
        if(upPriceSchoolList.size()>0)
            iCoursePriceSchoolService.updateBatchById(upPriceSchoolList,upPriceSchoolList.size());
        if(upCoursePricingList.size()>0)
            iCoursePricingService.updateBatchById(upCoursePricingList,upCoursePricingList.size());
        if(upAppointSchoolList.size()>0)
            iAppointSchoolService.updateBatchById(upAppointSchoolList,upAppointSchoolList.size());

        //更新排课信息里的课程科目，以后调整到异步修改
        UpdateWrapper<CourseSchedulingDetail> courseSchedulingDetailUpdateWrapper = new UpdateWrapper<>();
        Subjects subjects = iSubjectsService.getById(course.getSubjectsId());
        courseSchedulingDetailUpdateWrapper.eq("course_id",course.getId());
        courseSchedulingDetailUpdateWrapper.set("course_name",course.getName());
        courseSchedulingDetailUpdateWrapper.set("subjects_id",course.getSubjectsId());
        courseSchedulingDetailUpdateWrapper.set("subjects_name",subjects.getName());

        iCourseSchedulingDetailService.update(null,courseSchedulingDetailUpdateWrapper);
        this.updateById(course);

        if (course.getYearClassId() != courseOld.getYearClassId()){
            UpdateWrapper<Grade> gradeUpdateWrapper = new UpdateWrapper<>();
            gradeUpdateWrapper.set("year_class_id",course.getYearClassId());
            gradeUpdateWrapper.eq("course_id",course.getId());
            iGradeService.update(null,gradeUpdateWrapper);

            UpdateWrapper<StudentGrade> studentGradeUpdateWrapper = new UpdateWrapper<>();
            studentGradeUpdateWrapper.set("year_class_id",course.getYearClassId());
            studentGradeUpdateWrapper.eq("course_id",course.getId());
            iStudentGradeService.update(null,studentGradeUpdateWrapper);

        }
        if(courseOld.getQuarterNum()!= course.getQuarterNum()){
            UpdateWrapper<Grade> gradeUpdateWrapper = new UpdateWrapper<>();
            gradeUpdateWrapper.set("quarter_num",course.getQuarterNum());
            gradeUpdateWrapper.eq("course_id",course.getId());
            iGradeService.update(null,gradeUpdateWrapper);
        }
        return  true;
    }

    @Override
    public IPage<Course> checkCourse(IPage<?> page, Wrapper wrapper, Long schoolId){

        IPage<Course> courseIPage = courseMapper.checkCourse(page,wrapper);
        Iterator iterator = courseIPage.getRecords().iterator();

        for (Course course:courseIPage.getRecords()){
            Long courseId = course.getId();
            if (course.getLessonType() != null) {
                String lessonName = CommonUtil.getLessonTypeName(course.getLessonType());
                course.setCourseTypeName(lessonName);//
            }

            List<CoursePricing> coursePricingList = courseMapper.coursePricingForSchoolIdList(courseId,schoolId);
            course.setCoursePricingList(coursePricingList);
            Integer yearPart =  iQuarterService.getQuarterYearPartForNum(course.getQuarterNum());
            course.setYearPart(yearPart);//所属年份
            //获取班级开了该课程的班级
            List<Long> gradeIdList = new ArrayList<>();
            List<Grade> gradeList = iGradeService.getGradeForCheck(schoolId,courseId,yearPart,course.getQuarterNum(),gradeIdList,null);
            course.setGradeList(gradeList);
        }
        return courseIPage;
    }

    public IPage<Course> findAll(IPage<?> page,@Param(Constants.WRAPPER) Wrapper wrapper){
        IPage<Course> mapList = courseMapper.findAll(page,wrapper);
        return mapList;
    }

    public Course findOne(@Param("id") Long id){
        Course course  = courseMapper.findOne(id);
        return course;
    }

    public List<CoursePricing> coursePricingList(@Param("id") Long id){
            return  courseMapper.coursePricingList(id);
    }

    public List<CoursePricing> coursePricingForSchoolIdList(@Param("id") Long id,@Param("school_id") Long school_id){
        return  courseMapper.coursePricingList(id);
    }

    public IPage<StudentCourse> studentCourse(IPage<?> page,Wrapper wrapper,Integer lessonType){

        IPage<StudentCourse> studentCourseIPage = courseMapper.studentCourse(page,wrapper);
        for (StudentCourse studentCourse:studentCourseIPage.getRecords()){
            String state = iStudentGradeService.studentAtGradeStateForOrderDetailId(studentCourse.getId(),studentCourse.getStudentId(),1);
            studentCourse.setState(state);
            Long studentGradeCount = iStudentGradeService.getStudentGradeCount(studentCourse.getYearPart(),studentCourse.getQuarterNum(),studentCourse.getSchoolId(),studentCourse.getSubjectsId(),studentCourse.getStudentId());
            studentCourse.setStudentGradeCount(studentGradeCount);
            Long useCourseHouse = iStudentGradeService.getStudentUseCourseCount(studentCourse.getYearPart(),studentCourse.getQuarterNum(),studentCourse.getSchoolId(),studentCourse.getSubjectsId(),studentCourse.getStudentId(),lessonType);
            studentCourse.setUseCourseHouse(useCourseHouse);

            StudentNews studentNews = iStudentNewsService.getDataOne(studentCourse.getYearPart(),studentCourse.getQuarterNum(),studentCourse.getStudentId(),studentCourse.getSubjectsId());
            if (studentNews != null){
                studentCourse.setIsShowTempBtn(1);
            }
        }

        return studentCourseIPage;
    }

    public boolean deleteForId(Long id){


        QueryWrapper<OrderDetail> orderDetailQueryWrapper = new QueryWrapper<>();
        orderDetailQueryWrapper.eq("course_id",id);
        orderDetailQueryWrapper.ne("status",2);
        orderDetailQueryWrapper.ne("order_type",4);
        Long courseCount = orderDetailMapper.selectCount(orderDetailQueryWrapper);
        if(courseCount>0){
            throw new CommonException(ResultCode.ORDERDETAIL_COURESE_IN);
        }

        this.removeById(id);
        QueryWrapper<CoursePricing> queryWrapper =  new QueryWrapper<>();
        queryWrapper.eq("course_id",id);

        QueryWrapper<CoursePriceSchool> coursePriceSchoolQueryWrapper =  new QueryWrapper<>();
        coursePriceSchoolQueryWrapper.eq("course_id",id);

        this.iCoursePricingService.remove(queryWrapper);
        this.iCoursePriceSchoolService.remove(coursePriceSchoolQueryWrapper);

        return true;

    }
}
